package 左哥算法.ch17技巧篇.打印题;

import org.junit.Test;

import java.util.Arrays;

/**
 * 给你一个N*N的矩阵，要求你将他旋转90°
 */
public class Ch03旋转90度 {
    public void test1() {
        int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12},
                {13, 14, 15, 16}};
        Arrays.stream(matrix).forEach(o -> System.out.println(Arrays.toString(o)));
        System.out.println("--------------------");
        int[][] res = rotate(matrix);
        Arrays.stream(res).forEach(o -> System.out.println(Arrays.toString(o)));
    }

    public static int[][] rotate(int[][] matrix) {
        int[][] res = new int[matrix.length][matrix[0].length];
        int si = 0, sj = 0, ei = matrix.length - 1, ej = matrix[0].length - 1;
        while (sj <= ej) {
            fun(matrix, res, si, sj, ei, ej);
            si++;
            sj++;
            ei--;
            ej--;
        }
        return res;
    }

    public static void fun(int[][] matrix, int[][] target, int si, int sj, int ei, int ej) {
        int row = si;
        int clo = sj;
        while (row < ei) {
            target[row][ej] = matrix[si][clo];
            row++;
            clo++;
        }
        row = si;
        clo = ej;
        while (row < ei) {
            target[ei][clo] = matrix[row][ej];
            row++;
            clo--;
        }
        row = ei;
        clo = ej;
        while (row > si) {
            target[row][sj] = matrix[ei][clo];
            row--;
            clo--;
        }
        row = ei;
        clo = sj;
        while (row > si) {
            target[si][clo] = matrix[row][sj];
            row--;
            clo++;
        }
    }

    @Test
    public void test2() {
        int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12},
                {13, 14, 15, 16}};
        Arrays.stream(matrix).forEach(o -> System.out.println(Arrays.toString(o)));
        System.out.println("--------------------");
        rotate2(matrix);
        Arrays.stream(matrix).forEach(o -> System.out.println(Arrays.toString(o)));
    }

    /**
     * 方法2：在使用有限空间内完成
     */
    public static void rotate2(int[][] matrix) {
        int si = 0, sj = 0, ei = matrix.length - 1, ej = matrix[0].length - 1;
        while (sj <= ej) {
            fun(matrix, si, sj, ei, ej);
            si++;
            sj++;
            ei--;
            ej--;
        }
    }

    public static void fun(int[][] matrix, int si, int sj, int ei, int ej) {
        int i = sj;
        int row = si;
        while (i<ej){ //右侧和顶部互换
            swap(matrix, row, ej, si, i);
            i++;
            row++;
        }
        i=sj;
        int clo=ej;
        while (i<ej){ //底部和顶部互换
            swap(matrix, ei,clo, si, i);
            i++;
            clo--;
        }

        i=sj;
        row=ei;
        while (i<ej){ //左部和顶部互换
            swap(matrix, row,sj, si, i);
            i++;
            row--;
        }
    }

    public static void swap(int[][] matrix, int ai, int aj, int bi, int bj) {
        int temp = matrix[ai][aj];
        matrix[ai][aj] = matrix[bi][bj];
        matrix[bi][bj] = temp;
    }
}
